#'
#' @TODO 免疫检查点表达箱线图
#' @title 免疫检查点表达箱线图
#' @description 免疫检查点表达箱线图.
#' @param ImmuCheckPoint *character string*,免疫检查点gene Symbol，字符串向量,"PDCD1 (PD-1), CD274 (PD-L1), CTLA-4, CD80 (CTLA-4-L), ICOS, LAG3, and TNFRSF9 (4-1BB)."
#' @param exprs *data.frame*表达谱信息
#' @param clinical 临床信息,包含sample等其他临床信息，分析除sample外的其他临床分组信息间的表达差异,sample列内容需要和exprs中列名有交集
#' @param od 结果输出路径
#' @param w  *numric*，图宽
#' @param h  *numric*，图高
#' @param Color *character string*，分组间使用配色 默认使用Set1配色
#' @param n_row integer,整数，检查点信息分面展示，总共几行
#' @param SaveFile *Boolean*，是否保存突变在`od``
#' @param name *character string*，用于图片命名
#'
#' @return  a list
#' @export
#' @author *WYK*
#'
ImmuCheckPoint <- function(ImmuCheckPoint = c("CD274", "CD276", "CTLA4", "PDCD1"),
                           exprs = NULL, clinical = NULL, od = "./", w = 3, h = 3,
                           Color = NULL, n_row = 1, SaveFile = T, name = "ImmuCheckPoint") {
  library(tidyverse)
  require(ggprism)
  require(rstatix)
  require(ggpubr)

  ignoreCase <- c(
    "NA", "NAN", "NaN", "NX", "MX", "TX", "Not Reported", "GX", "UNK", "-", "", " ",
    "unknown", "UNknown", "notreported", "gx", NA
  )

  if (!dir.exists(od)) {
    dir.create(od, recursive = T)
  }

  if (is.null(Color)) {
    Color <- RColorBrewer::brewer.pal(8, "Set1")
  }

  immu_check_point <- ImmuCheckPoint # 四个主要的一定要有

  common_sample <- intersect(colnames(exprs), clinical$sample)
  immu_check_point_exp <- exprs[immu_check_point, common_sample] %>%
    na.omit() %>%
    t() %>%
    as.data.frame() %>%
    rownames_to_column(var = "sample") # nolint

  p_list <- map(setdiff(colnames(clinical), "sample"), function(x) {
    plot_dat <- inner_join(immu_check_point_exp, clinical) %>%
      pivot_longer(cols = -c("sample", x), names_to = "gene", values_to = "expr") %>% 
      distinct()

    plot_dat <- plot_dat[!{
      plot_dat[[x]] %in% ignoreCase
    }, ] 

    p <- plot_dat %>%
      ggplot(aes(x = factor(gene, levels = immu_check_point), y = expr)) +
      geom_boxplot(aes(fill = get0(x)),
        width = 0.55, outlier.size = 0.45,
        size = 0.65, alpha = 0.9
      ) +
      ggprism::theme_prism() +
      # theme_minimal(13) +
      theme(
        axis.text.x.bottom = element_blank(),
        axis.ticks.x.bottom = element_blank(),
        axis.title.x.bottom = element_blank(),
        axis.title.y.left = element_blank(),
        legend.position = "top",
        axis.text = element_text(colour = "black"),
        axis.line.x.bottom = element_blank()
      ) +
      # ggpubr::stat_compare_means(aes(group = get0(x), label = ..p.signif..)) +
      scale_fill_manual(values = Color) +
      guides(fill = guide_legend(title = x)) +
      scale_y_continuous(
        guide = "prism_offset"
      ) +
      facet_wrap(
        facets = c("gene"), scales = "free",
        nrow = n_row
      ) +
      ggplot2::coord_cartesian(clip = "off")

    formula.tmp <- as.formula(str_glue("expr ~ {x}"))

    if (length(unique(plot_dat[[x]])) == 2) {
      stat.test <- plot_dat %>%
        group_by(gene) %>%
        distinct() %>%
        wilcox_test(formula = formula.tmp) %>%
        # adjust_pvalue(method = "BH") %>%
        add_significance("p") %>%
        rstatix::add_xy_position(scales = c("free"))

      p <- p + stat_pvalue_manual(stat.test, label = "p.signif", x = "xmin")
      return(p)

    } else if (length(unique(plot_dat[[x]])) > 2) {
      stat.test <- plot_dat %>%
        group_by(gene) %>%
        distinct() %>% 
        kruskal_test(formula = formula.tmp) %>%
        # adjust_pvalue(method = "BH") %>%
        add_significance("p")

      stat.test$group1 <- as.character(plot_dat[[x]] %>% unique() %>% sort())[1]
      stat.test$group2 <- as.character(plot_dat[[x]] %>% unique() %>% sort())[2]
      stat.test$xmin <- 1
      stat.test$y.position <- 1.1 * max(plot_dat$expr)

      p <- p + stat_pvalue_manual(stat.test, label = "p.signif", x = "xmin") +
        guides(fill = guide_legend(nrow = 2))
      return(p)
    }
  })

  if (isTRUE(SaveFile)) {
    ggsave(
      plot = p_list[[1]], filename = str_glue("{od}/Figure_{name}.pdf"),
      width = w, height = h
    )
  }

  return(p_list[[1]])
}

# ImmuCheckPoint_data <-
# data.table::fread('/Pub/Data/Data_Center//GeneSet/immune_features/checkpoints_InAcMarker_extend.csv')
# ImmuCheckPoint_data$Role.with.Immunity %>% table() # Activate Active Inhibit
# TwoSide # 25 2 29 29 c('CD274', 'CD276', 'CTLA4', 'PDCD1', 'CD80', 'CD86')

#' @title  ImmuCheckPoint 通用情况
#' @inheritParams ImmuCheckPoint
#' @export
#' @param Feature 对应表达谱中的行名，可以是基因
#' @param GroupDF *character*，分组信息所在列，包含sample列，需要和exprs列名有交集
BoxplotInGroup <- function(Feature = c("CD274", "CD276", "CTLA4", "PDCD1"),
                           exprs = NULL, GroupDF = NULL, od = "./", w = 3, h = 3,
                           Color = NULL, n_row = 1, SaveFile = T, name = "ImmuCheckPoint") {
  library(tidyverse)
  require(ggprism)
  require(rstatix)
  require(ggpubr)

  ignoreCase <- c(
    "NA", "NAN", "NaN", "NX", "MX", "TX", "Not Reported", "GX", "UNK", "-", "", " ",
    "unknown", "UNknown", "notreported", "gx", NA
  )

  if (!dir.exists(od)) {
    dir.create(od, recursive = T)
  }

  if (is.null(Color)) {
    Color <- RColorBrewer::brewer.pal(8, "Set1")
  }

  # Feature # 四个主要的一定要有

  common_sample <- intersect(colnames(exprs), GroupDF$sample)
  Feature_exp <- exprs[Feature, common_sample] %>%
    na.omit() %>%
    t() %>%
    as.data.frame() %>%
    rownames_to_column(var = "sample") # nolint

  p_list <- map(setdiff(colnames(GroupDF), "sample"), function(x) {
    plot_dat <- inner_join(Feature_exp, GroupDF) %>%
      pivot_longer(cols = -c("sample", x), names_to = "gene", values_to = "expr")

    plot_dat <- plot_dat[!{
      plot_dat[[x]] %in% ignoreCase
    }, ]

    p <- plot_dat %>%
      ggplot(aes(x = factor(gene, levels = Feature), y = expr)) +
      geom_boxplot(aes(fill = get0(x)),
        width = 0.55, outlier.size = 0.45,
        size = 0.65, alpha = 0.9
      ) +
      facet_wrap(
        facets = c("gene"), scales = "free",
        nrow = n_row
      ) +
      ggprism::theme_prism() +
      # theme_minimal(13) +
      theme(
        axis.text.x.bottom = element_blank(),
        axis.ticks.x.bottom = element_blank(),
        axis.title.x.bottom = element_blank(),
        axis.title.y.left = element_blank(),
        legend.position = "top",
        axis.text = element_text(colour = "black"),
        axis.line.x.bottom = element_blank()
      ) +
      # ggpubr::stat_compare_means(aes(group = get0(x), label = ..p.signif..)) +
      scale_fill_manual(values = Color) +
      guides(fill = guide_legend(title = x)) +
      scale_y_continuous(
        guide = "prism_offset"
      )

    formula.tmp <- as.formula(str_glue("expr ~ {x}"))


    if (length(unique(plot_dat[[x]])) == 2) {
      stat.test <- plot_dat %>%
        group_by(gene) %>%
        distinct() %>%
        wilcox_test(formula = formula.tmp) %>%
        adjust_pvalue(method = "BH") %>%
        add_significance("p.adj") %>%
        rstatix::add_xy_position(scales = c("free"))
    } else if (length(unique(plot_dat[[x]])) > 2) {
      stat.test <- plot_dat %>%
        group_by(gene) %>%
        distinct() %>%
        kruskal_test(formula = formula.tmp) %>%
        adjust_pvalue(method = "BH") %>%
        add_significance("p.adj") %>%
        rstatix::add_xy_position()
    }

    p <- p + stat_pvalue_manual(stat.test, label = "p.adj.signif", x = "xmin")
    return(p)
  })

  if (isTRUE(SaveFile)) {
    ggsave(
      plot = p_list[[1]], filename = str_glue("{od}/Figure_{name}.pdf"),
      width = w, height = h
    )
  }

  return(p_list[[1]])
}
